#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
租赁合同管理系统模拟数据生成器

该模块用于为租赁合同管理系统自动生成符合业务规则的模拟测试数据。
支持自定义数据量、分布规则，并确保数据之间的关联性和逻辑性。

作者: AutoGenerator
版本: 1.0.0
日期: 2024-01-01
"""

import os
import sys
import random
import sqlite3
import argparse
import datetime
from typing import Dict, List, Optional, Any, Tuple, Callable
from datetime import datetime as dt
from datetime import timedelta

# 确保可以导入系统的db_utils
if os.path.dirname(os.path.abspath(__file__)) not in sys.path:
    sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))

try:
    from db_utils import DatabaseUtils
    from optimized_logging import log_debug, log_info, log_warning, log_error, log_exception
    HAS_SYSTEM_MODULES = True
except ImportError:
    HAS_SYSTEM_MODULES = False
    # 如果无法导入系统模块，使用内置的日志函数
    def log_debug(msg: str):
        print(f"[DEBUG] {msg}")
    
    def log_info(msg: str):
        print(f"[INFO] {msg}")
    
    def log_warning(msg: str):
        print(f"[WARNING] {msg}")
    
    def log_error(msg: str):
        print(f"[ERROR] {msg}")
    
    def log_exception(msg: str, ex: Exception = None):
        print(f"[EXCEPTION] {msg}: {str(ex) if ex else 'Unknown error'}")


class MockDataGenerator:
    """
    模拟数据生成器类，用于生成租赁合同管理系统的测试数据
    """
    
    def __init__(self, db_path: str = None, clear_existing: bool = False):
        """
        初始化模拟数据生成器
        
        Args:
            db_path: 数据库文件路径，如果不提供则使用系统默认路径
            clear_existing: 是否清除现有的测试数据
        """
        self.db_path = db_path or (DatabaseUtils.get_db_path() if HAS_SYSTEM_MODULES else "./lease_contract.db")
        self.clear_existing = clear_existing
        self.connection = None
        self.cursor = None
        
        # 配置参数
        self.config = {
            'random_seed': None,  # 随机种子，用于可重复的测试
            'include_edge_cases': True,  # 是否包含边界值
            'include_exceptional_cases': True,  # 是否包含异常情况
        }
        
        # 预设数据
        self._setup_preset_data()
    
    def _setup_preset_data(self):
        """
        设置预设数据，用于生成更真实的模拟数据
        """
        # 房屋类型
        self.house_types = ['一室一厅', '两室一厅', '三室一厅', '三室两厅', '四室两厅', '公寓', '商铺', '办公楼', '仓库']
        
        # 房屋用途
        self.usage_types = ['住宅', '商用', '办公', '仓储', '混合']
        
        # 房屋状态
        self.house_statuses = ['空闲', '已出租', '已预订', '维护中']
        
        # 合同状态
        self.contract_statuses = ['正常', '已到期', '已终止', '已续签', '即将到期']
        
        # 付款方式
        self.payment_methods = ['月付', '季付', '半年付', '年付']
        
        # 水电费计费方式
        self.utility_methods = ['按表计费', '固定费用', '全包']
        
        # 租金状态
        self.payment_statuses = ['未结清', '已结清', '部分结清', '已逾期']
        
        # 模拟城市区域
        self.city_districts = ['朝阳区', '海淀区', '东城区', '西城区', '丰台区', '石景山区', '通州区', '昌平区', '大兴区', '顺义区']
        
        # 模拟街道
        self.streets = ['建国路', '中关村大街', '东单北大街', '西单北大街', '丰台路', '石景山路', '运河东路', '回龙观东大街', '黄村西大街', '顺义大街']
        
        # 模拟小区
        self.communities = ['阳光小区', '幸福家园', '和谐小区', '美好家园', '花园小区', '绿色家园', '未来城', '城市之光', '东方明珠', '金色年华']
        
        # 模拟楼栋号
        self.building_nums = [f'{i}号楼' for i in range(1, 21)]
        
        # 模拟房间号
        self.room_nums = [f'{i}{j}{k}' for i in range(1, 31) for j in range(1, 5) for k in range(1, 7)]
    
    def connect(self) -> bool:
        """
        连接到数据库
        
        Returns:
            bool: 是否连接成功
        """
        try:
            self.connection = sqlite3.connect(self.db_path)
            self.cursor = self.connection.cursor()
            log_info(f"成功连接到数据库: {self.db_path}")
            
            # 设置随机种子（如果提供）
            if self.config['random_seed'] is not None:
                random.seed(self.config['random_seed'])
                log_info(f"已设置随机种子: {self.config['random_seed']}")
            
            # 如果需要清除现有数据
            if self.clear_existing:
                self._clear_existing_data()
            
            return True
        except Exception as e:
            log_error(f"连接数据库失败: {str(e)}")
            return False
    
    def disconnect(self):
        """
        断开数据库连接
        """
        try:
            if self.connection:
                self.connection.close()
                log_info("数据库连接已关闭")
        except Exception as e:
            log_error(f"关闭数据库连接失败: {str(e)}")
    
    def _clear_existing_data(self):
        """
        清除现有的测试数据，但保留关键的默认数据
        """
        try:
            log_info("开始清除现有测试数据...")
            
            # 需要清除数据的表（按依赖关系排序）
            tables_to_clear = [
                'rent_records',  # 依赖contracts
                'contracts',     # 依赖houses和tenants
                'houses',        # 独立表
                'tenants',       # 独立表
                'landlords',     # 独立表
                'notes',         # 独立表
                'operation_logs' # 独立表
                # 保留users, reminder_settings, system_params, utility_fee
            ]
            
            for table in tables_to_clear:
                try:
                    self.cursor.execute(f"DELETE FROM {table}")
                    self.connection.commit()
                    log_info(f"已清除表 {table} 的数据")
                except Exception as e:
                    log_warning(f"清除表 {table} 数据失败: {str(e)}")
                    self.connection.rollback()
        
        except Exception as e:
            log_error(f"清除数据过程中发生错误: {str(e)}")
            if self.connection:
                self.connection.rollback()
    
    def generate_mock_data(self, config: Dict[str, Any]) -> bool:
        """
        根据配置生成模拟数据
        
        Args:
            config: 配置参数，包含每种数据类型的生成数量和规则
                例如: {
                    'houses_count': 50,
                    'tenants_count': 100,
                    'contracts_count': 80,
                    'landlords_count': 10,
                    'rent_records_per_contract': 3
                }
                
        Returns:
            bool: 是否生成成功
        """
        try:
            if not self.connect():
                return False
            
            # 更新配置
            self.config.update(config)
            
            log_info("开始生成模拟数据...")
            
            # 生成顺序按照依赖关系：先生成被引用的表
            self._generate_house_types()
            self._generate_landlords(config.get('landlords_count', 10))
            self._generate_houses(config.get('houses_count', 50))
            self._generate_tenants(config.get('tenants_count', 100))
            self._generate_contracts(config.get('contracts_count', 80))
            self._generate_rent_records(config.get('rent_records_per_contract', 3))
            
            # 生成其他辅助数据
            self._generate_notes(config.get('notes_count', 20))
            
            # 提交所有更改
            self.connection.commit()
            log_info("模拟数据生成完成并已保存到数据库")
            return True
            
        except Exception as e:
            log_exception("生成模拟数据时发生错误", e)
            if self.connection:
                self.connection.rollback()
            return False
        finally:
            self.disconnect()
    
    def _generate_house_types(self):
        """
        生成房屋类型及其对应的水电费标准
        """
        try:
            log_info("生成房屋类型及水电费标准...")
            
            # 检查是否已有数据
            self.cursor.execute("SELECT COUNT(*) FROM utility_fee")
            if self.cursor.fetchone()[0] > 0:
                if not self.clear_existing:
                    log_info("utility_fee表已有数据，跳过生成")
                    return
            
            # 为每种房屋类型生成水电费标准
            for house_type in self.house_types:
                # 根据房屋类型确定不同的水电费率
                if '商铺' in house_type or '办公' in house_type:
                    water_fee = round(random.uniform(8.0, 12.0), 2)
                    electricity_fee = round(random.uniform(1.5, 2.5), 2)
                else:
                    water_fee = round(random.uniform(4.0, 7.0), 2)
                    electricity_fee = round(random.uniform(0.5, 1.0), 2)
                
                # 添加一些边界值和异常值
                if self.config['include_edge_cases'] and random.random() < 0.1:
                    water_fee = 0  # 免费
                
                if self.config['include_exceptional_cases'] and random.random() < 0.05:
                    water_fee = round(random.uniform(100.0, 500.0), 2)  # 极高的费用
                    electricity_fee = round(random.uniform(10.0, 20.0), 2)
                
                try:
                    self.cursor.execute(
                        "INSERT OR REPLACE INTO utility_fee (house_type, water_fee, electricity_fee) VALUES (?, ?, ?)",
                        (house_type, water_fee, electricity_fee)
                    )
                except Exception as e:
                    log_warning(f"插入房屋类型 {house_type} 失败: {str(e)}")
            
            log_info(f"已生成 {len(self.house_types)} 种房屋类型及水电费标准")
            
        except Exception as e:
            log_exception("生成房屋类型数据时发生错误", e)
            raise
    
    def _generate_landlords(self, count: int):
        """
        生成房东数据
        
        Args:
            count: 房东数量
        """
        try:
            log_info(f"生成 {count} 个房东数据...")
            
            # 预设的一些常用公司名称前缀
            company_prefixes = ['北京', '上海', '广州', '深圳', '天津', '杭州', '南京']
            company_suffixes = ['房地产开发有限公司', '置业有限公司', '物业管理有限公司', '房产经纪有限公司']
            
            # 预设的一些人名
            person_names = ['张三', '李四', '王五', '赵六', '钱七', '孙八', '周九', '吴十',
                           '郑十一', '王十二', '刘十三', '陈十四', '杨十五', '黄十六']
            
            # 生成房东数据
            created_count = 0
            for i in range(count):
                # 随机生成公司名称或个人名称
                is_company = random.random() > 0.3  # 70%为公司
                
                if is_company:
                    landlord_name = f"{random.choice(company_prefixes)}{random.choice(company_suffixes)}"
                    legal_representative = random.choice(person_names)
                    person_in_charge = random.choice(person_names)
                else:
                    landlord_name = random.choice(person_names)
                    legal_representative = None
                    person_in_charge = None
                
                # 生成联系电话
                contact_phone = f"13{random.randint(0, 9)}{random.randint(0, 9)}{random.randint(0, 9)}{random.randint(0, 9)}{random.randint(0, 9)}{random.randint(0, 9)}{random.randint(0, 9)}{random.randint(0, 9)}{random.randint(0, 9)}"
                
                # 生成地址
                address = f"{random.choice(self.city_districts)}{random.choice(self.streets)}{random.randint(1, 100)}号"
                
                # 设置默认房东（第一个为默认）
                is_default = 1 if i == 0 else 0
                
                # 添加一些边界值和异常值
                if self.config['include_edge_cases'] and random.random() < 0.1:
                    contact_phone = ""
                
                if self.config['include_exceptional_cases'] and random.random() < 0.05:
                    landlord_name = "测试异常_!@#$%^&*()"
                
                try:
                    self.cursor.execute(
                        "INSERT INTO landlords (landlord_name, legal_representative, person_in_charge, contact_phone, is_default) VALUES (?, ?, ?, ?, ?)",
                        (landlord_name, legal_representative, person_in_charge, contact_phone, is_default)
                    )
                    created_count += 1
                except Exception as e:
                    log_warning(f"插入房东数据失败: {str(e)}")
            
            log_info(f"已成功生成 {created_count} 个房东数据")
            
        except Exception as e:
            log_exception("生成房东数据时发生错误", e)
            raise
    
    def _generate_houses(self, count: int):
        """
        生成房屋数据
        
        Args:
            count: 房屋数量
        """
        try:
            log_info(f"生成 {count} 个房屋数据...")
            
            created_count = 0
            # 跟踪已生成的房屋编号
            house_nos = set()
            
            for i in range(count):
                # 生成唯一的房屋编号
                while True:
                    house_no = f"F{random.randint(10000, 99999)}"
                    if house_no not in house_nos:
                        house_nos.add(house_no)
                        break
                
                # 生成房屋位置
                district = random.choice(self.city_districts)
                street = random.choice(self.streets)
                community = random.choice(self.communities)
                building = random.choice(self.building_nums)
                room = random.choice(self.room_nums)
                
                house_location = f"{district}{street}{community}{building}{room}"
                
                # 生成房屋面积
                house_type = random.choice(self.house_types)
                
                # 根据房屋类型确定面积范围
                if '一室' in house_type:
                    min_area, max_area = 30, 60
                elif '两室' in house_type:
                    min_area, max_area = 50, 90
                elif '三室' in house_type:
                    min_area, max_area = 80, 130
                elif '四室' in house_type:
                    min_area, max_area = 120, 180
                elif '公寓' in house_type:
                    min_area, max_area = 20, 50
                elif '商铺' in house_type:
                    min_area, max_area = 40, 200
                elif '办公' in house_type:
                    min_area, max_area = 60, 300
                elif '仓库' in house_type:
                    min_area, max_area = 100, 1000
                else:
                    min_area, max_area = 50, 120
                
                house_area = round(random.uniform(min_area, max_area), 2)
                
                # 生成用途和状态
                usage = random.choice(self.usage_types)
                status = random.choice(self.house_statuses)
                
                # 添加一些边界值和异常值
                if self.config['include_edge_cases'] and random.random() < 0.1:
                    house_area = 0.1  # 极小面积
                
                if self.config['include_exceptional_cases'] and random.random() < 0.05:
                    house_area = 9999.99  # 极大面积
                
                try:
                    self.cursor.execute(
                        "INSERT INTO houses (house_no, house_location, house_area, house_type, usage) VALUES (?, ?, ?, ?, ?)",
                        (house_no, house_location, house_area, house_type, usage)
                    )
                    created_count += 1
                except Exception as e:
                    log_warning(f"插入房屋数据失败: {str(e)}")
            
            log_info(f"已成功生成 {created_count} 个房屋数据")
            
        except Exception as e:
            log_exception("生成房屋数据时发生错误", e)
            raise
    
    def _generate_tenants(self, count: int):
        """
        生成租户数据
        
        Args:
            count: 租户数量
        """
        try:
            log_info(f"生成 {count} 个租户数据...")
            
            # 预设的一些人名
            person_names = ['张三', '李四', '王五', '赵六', '钱七', '孙八', '周九', '吴十',
                           '郑十一', '王十二', '刘十三', '陈十四', '杨十五', '黄十六',
                           '张A', '李B', '王C', '赵D', '钱E', '孙F', '周G', '吴H']
            
            # 预设的一些公司名称
            company_names = ['ABC科技有限公司', 'XYZ贸易公司', '未来发展企业', '科技创新工作室', '诚信商贸有限公司',
                           '卓越服务公司', '星辰大海集团', '智慧城市建设', '绿色环保科技', '数字经济研究院']
            
            created_count = 0
            
            for i in range(count):
                # 随机生成个人或公司租户
                is_company = random.random() > 0.6  # 40%为公司
                
                if is_company:
                    tenant_name = random.choice(company_names) + str(random.randint(1, 100))
                    contact_person = random.choice(person_names)
                    # 公司使用统一社会信用代码格式
                    contact_id = f"{random.randint(10000000, 99999999)}" + \
                                 f"{random.randint(0, 9)}{random.randint(0, 9)}" + \
                                 f"{random.choice('QWERTYUIOPASDFGHJKLZXCVBNM')}"
                else:
                    tenant_name = random.choice(person_names)
                    contact_person = tenant_name  # 个人租户联系人就是自己
                    # 个人使用身份证号码格式
                    contact_id = f"{random.randint(110000, 999999)}" + \
                                 f"{random.randint(1950, 2000):04d}" + \
                                 f"{random.randint(1, 12):02d}{random.randint(1, 28):02d}" + \
                                 f"{random.randint(100, 999)}{random.choice('0123456789X')}"
                
                # 生成联系电话
                contact_phone = f"13{random.randint(0, 9)}{random.randint(0, 9)}{random.randint(0, 9)}{random.randint(0, 9)}{random.randint(0, 9)}{random.randint(0, 9)}{random.randint(0, 9)}{random.randint(0, 9)}{random.randint(0, 9)}"
                
                # 添加一些边界值和异常值
                if self.config['include_edge_cases'] and random.random() < 0.1:
                    contact_phone = ""  # 空电话号码
                
                if self.config['include_exceptional_cases'] and random.random() < 0.05:
                    contact_id = "111111111111111111"  # 无效身份证
                
                try:
                    self.cursor.execute(
                        "INSERT INTO tenants (tenant_name, contact_person, contact_id, contact_phone) VALUES (?, ?, ?, ?)",
                        (tenant_name, contact_person, contact_id, contact_phone)
                    )
                    created_count += 1
                except Exception as e:
                    log_warning(f"插入租户数据失败: {str(e)}")
            
            log_info(f"已成功生成 {created_count} 个租户数据")
            
        except Exception as e:
            log_exception("生成租户数据时发生错误", e)
            raise
    
    def _generate_contracts(self, count: int):
        """
        生成合同数据
        
        Args:
            count: 合同数量
        """
        try:
            log_info(f"生成 {count} 个合同数据...")
            
            # 获取现有的房源和租户
            self.cursor.execute("SELECT id, house_no, house_location, house_area, house_type, usage FROM houses")
            houses = self.cursor.fetchall()
            
            # 调试：打印房屋数据结构
            if houses:
                log_info(f"房屋数据样例: {houses[0]}")
                log_info(f"房屋面积字段索引位置: 3, 值: {houses[0][3]}, 类型: {type(houses[0][3])}")
            
            self.cursor.execute("SELECT id, tenant_name, contact_person, contact_id, contact_phone FROM tenants")
            tenants = self.cursor.fetchall()
            
            self.cursor.execute("SELECT id, landlord_name, legal_representative, person_in_charge, contact_phone FROM landlords")
            landlords = self.cursor.fetchall()
            
            if not houses or not tenants or not landlords:
                log_error("无法生成合同数据，缺少必要的房屋、租户或房东数据")
                return
            
            created_count = 0
            # 跟踪已生成的合同编号
            contract_nos = set()
            # 跟踪已使用的房屋ID，以确保一个房屋在同一时间只有一个有效合同
            used_houses = set()
            
            for i in range(count):
                # 生成唯一的合同编号
                while True:
                    year = random.randint(2020, 2024)
                    month = random.randint(1, 12)
                    contract_no = f"HT{year}{month:02d}{random.randint(1000, 9999)}"
                    if contract_no not in contract_nos:
                        contract_nos.add(contract_no)
                        break
                
                # 选择一个随机的房东
                landlord = random.choice(landlords)
                
                # 选择一个未被使用的房屋或有一定概率重复使用（模拟到期后重新出租）
                reuse_house = random.random() < 0.1  # 10%的概率重用房屋
                
                if not reuse_house and len(used_houses) < len(houses):
                    # 尝试找到未使用的房屋
                    available_houses = [h for h in houses if h[0] not in used_houses]
                    if available_houses:
                        house = random.choice(available_houses)
                        used_houses.add(house[0])
                    else:
                        # 所有房屋都已使用，随机选择一个
                        house = random.choice(houses)
                else:
                    house = random.choice(houses)
                
                # 选择一个随机的租户
                tenant = random.choice(tenants)
                
                # 生成签约日期
                sign_date = (dt.now() - timedelta(days=random.randint(1, 1095))).strftime("%Y-%m-%d")
                sign_year_month = sign_date[:7]  # YYYY-MM格式
                
                # 生成合同开始日期（通常在签约日期之后或当天）
                start_date = (dt.strptime(sign_date, "%Y-%m-%d") + timedelta(days=random.randint(0, 30))).strftime("%Y-%m-%d")
                
                # 生成合同结束日期（通常为1-5年）
                contract_years = random.randint(1, 5)
                end_date = (dt.strptime(start_date, "%Y-%m-%d") + timedelta(days=contract_years*365)).strftime("%Y-%m-%d")
                
                # 确定合同状态（符合系统预设规则：执行中、已完成、已逾期）
                today = dt.now().strftime("%Y-%m-%d")
                if end_date < today:
                    # 已过期的合同标记为已完成或已逾期
                    if random.random() < 0.7:
                        status = '已完成'
                    else:
                        status = '已逾期'
                else:
                    # 未过期的合同为执行中
                    status = '执行中'
                
                # 生成付款方式
                payment_method = random.choice(self.payment_methods)
                
                # 根据房屋面积和类型计算月租
                base_rent_per_sqm = 0
                if '商铺' in house[4] or '办公' in house[4]:
                    base_rent_per_sqm = random.uniform(10, 30)
                else:
                    base_rent_per_sqm = random.uniform(5, 20)
                
                # 使用正确的索引获取面积字段（索引3）
                house_area = house[3]  # 已经是float类型，不需要再转换
                monthly_rent = int(base_rent_per_sqm * house_area)
                quarterly_rent = int(monthly_rent * 3) if payment_method in ['季付', '半年付', '年付'] else None
                annual_rent = int(monthly_rent * 12)
                total_rent = int(annual_rent * contract_years)
                
                # 押金通常为1-3个月房租
                deposit = int(monthly_rent * random.randint(1, 3))
                
                # 水电费计费方式
                utility_method = random.choice(self.utility_methods)
                
                # 如果是固定费用，设置水电费用
                water_fee = None
                electricity_fee = None
                if utility_method == '固定费用':
                    water_fee = round(random.uniform(100, 500), 2)
                    electricity_fee = round(random.uniform(200, 1000), 2)
                
                # 备注
                remarks = None
                if random.random() < 0.2:
                    remarks = f"合同备注: {random.randint(1, 100)}"
                
                # 添加一些边界值和异常值
                if self.config['include_edge_cases'] and random.random() < 0.1:
                    monthly_rent = 1  # 极小租金（整数）
                
                if self.config['include_exceptional_cases'] and random.random() < 0.05:
                    monthly_rent = 99999  # 极高租金（整数）
                    end_date = (dt.now() - timedelta(days=10)).strftime("%Y-%m-%d")  # 已过期
                    # 即使在异常情况下也使用正确的状态值
                    status = '已逾期'
                
                try:
                    self.cursor.execute(
                        '''INSERT INTO contracts 
                        (contract_no, sign_date, sign_year_month, house_no, house_location, house_area, 
                        lessor, legal_representative, person_in_charge, contact_phone, 
                        lessee, tenant, tenant_id, tenant_phone, 
                        start_date, end_date, status, payment_method, 
                        monthly_rent, quarterly_rent, total_rent, annual_rent, deposit, 
                        usage, utility_method, water_fee, electricity_fee, remarks) 
                        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',
                        (
                            contract_no, sign_date, sign_year_month, house[1], house[2], house[3],
                            landlord[1], landlord[2], landlord[3], landlord[4],
                            tenant[1], tenant[1], tenant[3], tenant[4],
                            start_date, end_date, status, payment_method,
                            monthly_rent, quarterly_rent, total_rent, annual_rent, deposit,
                            house[5], utility_method, water_fee, electricity_fee, remarks
                        )
                    )
                    created_count += 1
                except Exception as e:
                    log_warning(f"插入合同数据失败: {str(e)}")
            
            log_info(f"已成功生成 {created_count} 个合同数据")
            
        except Exception as e:
            log_exception("生成合同数据时发生错误", e)
            raise
    
    def _generate_rent_records(self, per_contract: int):
        """
        为每个合同生成租金记录
        
        Args:
            per_contract: 每个合同生成的租金记录数量
        """
        try:
            log_info(f"为每个合同生成 {per_contract} 条租金记录...")
            
            # 获取所有合同
            self.cursor.execute("SELECT id, contract_no, lessee, tenant, start_date, end_date, monthly_rent, payment_method FROM contracts")
            contracts = self.cursor.fetchall()
            
            if not contracts:
                log_error("无法生成租金记录，没有找到合同数据")
                return
            
            created_count = 0
            
            # 预设的一些账户
            accounts = ['招商银行', '建设银行', '工商银行', '中国银行', '农业银行', '支付宝', '微信支付']
            
            for contract in contracts:
                # 确定为这个合同生成多少条记录
                actual_records = random.randint(1, per_contract)
                
                # 根据合同的付款方式和时间计算租金周期
                start_date = dt.strptime(contract[4], "%Y-%m-%d")
                end_date = dt.strptime(contract[5], "%Y-%m-%d")
                
                # 租金周期（天）
                if contract[7] == '月付':
                    period_days = 30
                elif contract[7] == '季付':
                    period_days = 90
                elif contract[7] == '半年付':
                    period_days = 180
                elif contract[7] == '年付':
                    period_days = 365
                else:
                    period_days = 30  # 默认月付
                
                # 生成租金记录
                current_date = start_date
                for i in range(actual_records):
                    # 计算本期开始和结束日期
                    period_start = current_date.strftime("%Y-%m-%d")
                    period_end = (current_date + timedelta(days=period_days-1)).strftime("%Y-%m-%d")
                    
                    # 确保不超过合同结束日期
                    if period_end > contract[5]:
                        break
                    
                    # 收款日期（通常在周期开始后几天到几个月）
                    receipt_days = random.randint(1, 60)
                    receipt_date = (current_date + timedelta(days=receipt_days)).strftime("%Y-%m-%d")
                    
                    # 根据付款方式计算金额
                    if contract[7] == '月付':
                        amount = contract[6]
                    elif contract[7] == '季付':
                        amount = round(contract[6] * 3, 2)
                    elif contract[7] == '半年付':
                        amount = round(contract[6] * 6, 2)
                    elif contract[7] == '年付':
                        amount = round(contract[6] * 12, 2)
                    else:
                        amount = contract[6]
                    
                    # 随机选择账户
                    account = random.choice(accounts) if random.random() > 0.2 else None  # 20%概率不填账户
                    
                    # 发票日期（可能为空）
                    invoice_date = None
                    if random.random() > 0.3:  # 70%概率有发票
                        invoice_days = random.randint(0, 15)
                        invoice_date = (dt.strptime(receipt_date, "%Y-%m-%d") + timedelta(days=invoice_days)).strftime("%Y-%m-%d")
                    
                    # 描述
                    description = f"{period_start}至{period_end}租金"
                    
                    # 付款状态
                    today = dt.now().strftime("%Y-%m-%d")
                    if receipt_date <= today:
                        # 已过收款日期，可能已结清
                        if random.random() > 0.2:  # 80%概率已结清
                            payment_status = '已结清'
                        elif random.random() > 0.5:  # 10%概率部分结清
                            payment_status = '部分结清'
                            amount = round(amount * random.uniform(0.2, 0.8), 2)  # 随机部分金额
                        else:  # 10%概率已逾期
                            payment_status = '已逾期'
                    else:
                        # 未到收款日期
                        payment_status = '未结清'
                    
                    # 添加一些边界值和异常值
                    if self.config['include_edge_cases'] and random.random() < 0.1:
                        amount = 0.01  # 极小金额
                    
                    if self.config['include_exceptional_cases'] and random.random() < 0.05:
                        amount = round(random.uniform(10000, 100000), 2)  # 异常大额
                        receipt_date = (dt.now() + timedelta(days=365)).strftime("%Y-%m-%d")  # 未来收款
                        payment_status = '已结清'  # 但状态为已结清
                    
                    try:
                        self.cursor.execute(
                            '''INSERT INTO rent_records 
                            (contract_no, lessee, tenant, receipt_date, amount, 
                            period_start, period_end, account, invoice_date, description, payment_status) 
                            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',
                            (
                                contract[1], contract[2], contract[3], receipt_date, amount,
                                period_start, period_end, account, invoice_date, description, payment_status
                            )
                        )
                        created_count += 1
                    except Exception as e:
                        log_warning(f"插入租金记录失败: {str(e)}")
                    
                    # 更新当前日期为下一个周期
                    current_date += timedelta(days=period_days)
            
            log_info(f"已成功生成 {created_count} 条租金记录")
            
        except Exception as e:
            log_exception("生成租金记录时发生错误", e)
            raise
    
    def _generate_notes(self, count: int):
        """
        生成笔记数据
        
        Args:
            count: 笔记数量
        """
        try:
            log_info(f"生成 {count} 个笔记数据...")
            
            # 预设的一些笔记标题
            note_titles = [
                '房屋交接注意事项', '租户管理规定', '租金收取流程', '合同续签流程',
                '房屋维修申请流程', '水电费结算说明', '紧急联系人清单', '系统操作指南',
                '常见问题解答', '租户投诉处理流程', '房屋检查清单', '合同变更流程',
                '房屋保险说明', '租户退租流程', '新租户入住流程', '房东信息变更流程'
            ]
            
            created_count = 0
            # 跟踪已生成的笔记名称
            note_names = set()
            
            for i in range(count):
                # 生成唯一的笔记名称
                base_title = random.choice(note_titles)
                # 添加时间戳和随机数确保唯一性
                timestamp = dt.now().strftime("%H%M%S")
                random_id = random.randint(100, 999)
                note_name = f"{base_title}-{timestamp}-{random_id}"
                note_names.add(note_name)
                
                # 生成创建时间（过去1年内）
                created_at = (dt.now() - timedelta(days=random.randint(1, 365))).strftime("%Y-%m-%d %H:%M:%S")
                
                # 生成更新时间（在创建时间之后，可能就是创建时间）
                days_after_created = random.randint(0, (dt.now() - dt.strptime(created_at[:10], "%Y-%m-%d")).days)
                updated_at = (dt.strptime(created_at, "%Y-%m-%d %H:%M:%S") + timedelta(days=days_after_created)).strftime("%Y-%m-%d %H:%M:%S")
                
                # 生成笔记内容
                content = f"这是 {note_name} 的详细内容。\n\n"
                content += f"创建于: {created_at}\n"
                content += f"更新于: {updated_at}\n\n"
                content += "本文档包含相关的政策规定和操作流程说明。\n"
                content += "请相关人员严格按照流程执行，确保管理工作的规范性。\n"
                content += "如有疑问，请联系管理员。\n"
                
                # 随机添加一些额外内容
                if random.random() > 0.5:
                    content += f"\n备注: {random.randint(1, 1000)}"
                
                try:
                    self.cursor.execute(
                        "INSERT INTO notes (note_name, content, created_at, updated_at) VALUES (?, ?, ?, ?)",
                        (note_name, content, created_at, updated_at)
                    )
                    created_count += 1
                except Exception as e:
                    log_warning(f"插入笔记数据失败: {str(e)}")
            
            log_info(f"已成功生成 {created_count} 个笔记数据")
            
        except Exception as e:
            log_exception("生成笔记数据时发生错误", e)
            raise


def parse_arguments():
    """
    解析命令行参数
    """
    parser = argparse.ArgumentParser(description='租赁合同管理系统模拟数据生成器')
    
    # 数据库路径
    parser.add_argument('-d', '--db-path', type=str, default=None,
                        help='数据库文件路径，默认为系统默认路径')
    
    # 是否清除现有数据
    parser.add_argument('-c', '--clear', action='store_true',
                        help='是否清除现有的测试数据')
    
    # 生成的数据量
    parser.add_argument('--houses', type=int, default=50,
                        help='生成的房屋数量，默认50')
    
    parser.add_argument('--tenants', type=int, default=100,
                        help='生成的租户数量，默认100')
    
    parser.add_argument('--contracts', type=int, default=80,
                        help='生成的合同数量，默认80')
    
    parser.add_argument('--landlords', type=int, default=10,
                        help='生成的房东数量，默认10')
    
    parser.add_argument('--rent-records', type=int, default=3,
                        help='每个合同生成的租金记录数量，默认3')
    
    parser.add_argument('--notes', type=int, default=20,
                        help='生成的笔记数量，默认20')
    
    # 是否包含边界值和异常数据
    parser.add_argument('--no-edge-cases', action='store_true',
                        help='不包含边界值数据')
    
    parser.add_argument('--no-exceptional-cases', action='store_true',
                        help='不包含异常情况数据')
    
    # 随机种子，用于可重复的测试
    parser.add_argument('--seed', type=int, default=None,
                        help='随机种子，用于生成可重复的测试数据')
    
    return parser.parse_args()


def main():
    """
    主函数
    """
    # 解析命令行参数
    args = parse_arguments()
    
    # 创建数据生成器
    generator = MockDataGenerator(
        db_path=args.db_path,
        clear_existing=args.clear
    )
    
    # 配置数据生成参数
    config = {
        'houses_count': args.houses,
        'tenants_count': args.tenants,
        'contracts_count': args.contracts,
        'landlords_count': args.landlords,
        'rent_records_per_contract': args.rent_records,
        'notes_count': args.notes,
        'include_edge_cases': not args.no_edge_cases,
        'include_exceptional_cases': not args.no_exceptional_cases,
        'random_seed': args.seed
    }
    
    # 生成模拟数据
    success = generator.generate_mock_data(config)
    
    if success:
        log_info("模拟数据生成任务完成")
        sys.exit(0)
    else:
        log_error("模拟数据生成任务失败")
        sys.exit(1)


if __name__ == "__main__":
    main()
